Sections |
||||
Generic Header Format | Graphic File Formats | Archive File Formats | Sound File Formats | Custom File Formats |
Compression Formats |
File Formats |
||||
NCLR | NCGR | NSCR | NANR | NCER |
NARC | SDAT | |||
PAK |
Archive File Formats |
|||
Nintendo Archive (ARC/NARC) - uses Generic Header - magic ID is #NARC (0x4E415243) - contains 3 sub-sections |
|||
#1 Section - File Allocation Table (BTAF) | |||
Offset | Length | Name | Description |
0x0 | 0x4 | Magic ID | #BTAF (0x42544146) |
0x4 | 0x1 | Header Size | |
0x4 | 0x4 | Section Size | Size of this section, including the header. |
0x8 | 0x4 | Number of Files | The number of files in the archive. |
DATA | See below. | ||
0xC | 0x4 | Start Offset | Is RELATIVE to the GMIF section start offset. |
0x10 | 0x4 | End Offset | Is RELATIVE to the GMIF section start offset. |
#2 Section - File Name Table (BTNF) | |||
0x0 | 0x4 | Magic ID | #BTNF (0x42544E46) |
0x4 | 0x4 | Section Size | Size of this section, including the header. |
DATA | Directory Table | ||
0x4 | Directory Start Offset | All other offsets are RELATIVE to the first directory start offset which is the root folder. | |
0x2 | First File Position | ||
0x2 | Directory Count / Parent Directory | For the root folder it has the total number of directories in the archive, and the latter for everything else. | |
DATA | Name Table | ||
0x1 | Size of Name | The first bit specifies whether it is a file or a folder. | |
0xLENGTH | Name String | ||
EXTRA | 0x2 | Directory ID | The number reference of that directory. |
#3 Section - File Image (GMIF) | |||
0x0 | 0x4 | Magic ID | #GMIF (0x474D4946) |
0x4 | 0x4 | Section Size | Size of this section, including the header. |
0x8 | 0x4 | Compression ID | #LZ77 (0x4C5A3737) Indicates that the file data is compressed. |
Sound File Formats |
|||
Sound Data File (SDAT) - uses Generic Header - magic ID is #SDAT (0x53444154) - contains 4 sub-sections |
|||
Section Offsets | |||
Offset | Length | Name | Description |
0x0 | 0x4 | SYMB Offset | Offset to SYMB Section |
0x4 | 0x4 | SYMB Size | Size of SYMB Section |
0x8 | 0x4 | INFO Offset | Offset to INFO Section |
0xC | 0x4 | INFO Size | Size of INFO Section |
0x10 | 0x4 | FAT Offset | Offset to FAT Section |
0x14 | 0x4 | FAT Size | Size of FAT Section |
0x18 | 0x4 | FILE Offset | Offset to FILE Section |
0x1C | 0x4 | FILE Size | Size of FILE Section |
0x20 | 0x16 | Padding | |
#1 Section - (SYMB) | |||
0x0 | 0x4 | Magic ID | #SYMB (0x53594D42) |
0x4 | 0x4 | Section Size | Size of this section, including the header. |
0x8 | 0x4 | Sequences Offset | |
0xC | 0x4 | Sound Effects Offset | |
0x10 | 0x4 | Banks Offset | |
0x14 | 0x4 | Waves Offset | |
0x18 | 0x4 | Players Offset | |
0x1C | 0x4 | Groups Offset | |
0x20 | 0x4 | Streams Offset | |
0x24 | 0x4 | Unknown Offset | |
0x28 | 0x24 | Padding | |
DATA | |||
0x40 | 0x4 | Number of Files | The number of files in this section |
0x44 | 0x4 | Filename Offset | Offset is RELATIVE to each section offset |
#2 Section - Information (INFO) | |||
0x0 | 0x4 | Magic ID | #INFO (0x?) |
0x4 | 0x4 | Section Size | Size of this section, including the header. |
0x8 | 0x4 | Sequences Offset | |
0xC | 0x4 | Sound Effects Offset | |
0x10 | 0x4 | Banks Offset | |
0x14 | 0x4 | Waves Offset | |
0x18 | 0x4 | Players Offset | |
0x1C | 0x4 | Groups Offset | |
0x20 | 0x4 | Streams Offset | |
0x24 | 0x4 | Unknown Offset | |
0x28 | 0x24 | Padding | |
DATA | |||
0x4 | Number of Elements | ||
0x4 | Offset to First Element | ||
0x4 | ID of Current Element | ||
0x8 | Sequences Variables | ||
0x8 | Banks Variables | ||
0x8 | Players Variables | ||
0x8 | Groups Variables | ||
#3 Section - FIle Allocation Table (FAT) | |||
0x0 | 0x4 | Magic ID | #FAT (0x?) |
0x4 | 0x4 | Section Size | Size of this section, including the header. |
0x8 | 0x4 | Number of Files | |
DATA | FAT Table (Repeats) | ||
0x4 | File Offset | ||
0x4 | File Size | ||
0x8 | Unknown | ||
#4 Section - File Data (FILE) | |||
0x0 | 0x4 | Magic ID | #FILE (0x?) |
0x4 | 0x4 | Section Size | Size of this section, including the header. |
0x8 | 0x4 | Number of Files | |
0xC | 0x4 | Unknown | |
Sound Sequence (SSEQ) - uses Generic Header - magic ID is #SSEQ (0x?) - contains only one section? |
|||
#1 Section - Sequence Data (DATA) | |||
0x0 | 0x4 | Magic ID | #DATA (0x?) |
0x4 | 0x4 | Section Size | Size of this section, including the header. |
0x8 | 0x4 | Start Offset | The offset to where the notation data begins. |
0xC | 0x3 | Track Description (Command) | |
DATA | (Track Reference which repeats for the number of tracks) | ||
0x4 | Open Track (Command) | Fist bytes is the command code, second byte is the track number, and the last 2 bytes are the track offet. | |
DATA | |||
0x3 | Set Mono/Poly (Command) | ||
0x3 | Set Tempo (Command) | ||
Sequence Commands | |||
Code | Value Length | Name | Description |
0x00 - 0x7F | 0x2 | Music Note | Format is (0xVVDD) V2 = Velocity D2 = Duration |
0x80 | 0x1 | Rest Note | Duration of rest note. |
0x81 | 0x1 | Change Instrument | Instrument number to change to. |
0x93 | 0x4 | Open Track | Format is (0xAABBBBBB) A2 = Track number B6 = Track offset (RELATIVE to the start offset) |
0x94 | 0x3 | Jump | Move to postion in the track and loop. |
0x95 | 0x3 | Call | Move to the start of another track. |
0xC0 | 0x1 | Channel Panning | Set panning value (-128 to 127) |
0xC1 | 0x1 | Channel Volume | Set volume |
0xC2 | 0x1 | Global Volume | Set the sequence volume |
0xC3 | 0x1 | Transpose | |
0xC4 | 0x1 | Portamento | |
0xC5 | 0x1 | Portamento Range | |
0xC6 | 0x1 | Priority | Set the priority of the track. |
0xC7 | 0x1 | Mono / Poly | Set the phonie 0 = Polyphonie 1 = Monophonie |
0xCA | 0x1 | Vibrato Depth | |
0xCB | 0x1 | Vibrato Speed | |
0xE1 | 0x1 | Tempo | Set the tempo. |
0xFD | 0x0 | Return | Return from the previous "Call" command. |
0xFE | 0x2 | Track Description | Number of tracks and their position. |
0xFF | 0x0 | End | End of the track. |
Sound Sequence Archive (SSAR) - uses Generic Header - magic ID is #SSAR (0x?) - contains only 1 section |
|||
#1 Section - Data (DATA) | |||
Offset | Length | Name | Description |
0x0 | 0x4 | Magic ID | #DATA (0x?) |
0x4 | 0x4 | Section Size | Size of this section, including the header. |
0x8 | 0x4 | Unknown Offset | |
0xC | 0x4 | Number of elements | |
0x10 | 0x4 | Padding | Always (0x0) |
DATA | |||
0x8 | Unknown | ||
0x4 | Data Offset | RELATIVE to Unknown Offset | |
DATA | Actual Data | ||
Sound Wave Archive (SWAR) - uses Generic Header - magic ID is #SWAR (0x?) - contains only 1 section |
|||
#1 Section - Data (DATA) | |||
Offset | Length | Name | Description |
0x0 | 0x4 | Magic ID | #DATA (0x?) |
0x4 | 0x4 | Section Size | Size of this section, including the header. |
0x8 | 0x32 | Unknown | |
0x28 | 0x4 | Number of Files | |
DATA | Repeats by Number of Files. | ||
0x2C | 0x4 | Wave Offset | RELATIVE to the start of the file. |
DATA | Data at Wave Offset. | ||
0x0 | 0x1 | Wave Type | 0 = PCM 8Bit 1 = PCM 16Bit 2 = ADPCM |
0x1 | 0x1 | Loop Support | 0 = False 1 = True |
0x2 | 0x2 | Sample Rate | |
0x4 | 0x2 | Duration | |
0x6 | 0x2 | Loop Start | Multiply by 4. |
0x8 | 0x4 | Loop Length | Multiply by 4. |
DATA | Wave Data | ||
Sound Bank (SBNK) - uses Generic Header - magic ID is #SBNK (0x?) - contains only 1 section |
|||
#1 Section - Data (DATA) | |||
Offset | Length | Name | Description |
0x0 | 0x4 | Magic ID | #DATA (0x?) |
0x4 | 0x4 | Section Size | Size of this section, including the header. |
0x8 | 0x32 | Unknown | |
0x28 | 0x4 | Number of Samples | |
0x2C | 0x1 | Unknown Type | |
DATA | |||
0x2D | 0x3 | Data Offset | RELATIVE to the start of the file. |
DATA | Sample Data | ||
0x0 | 0x2 | Sample Number | |
0x2 | 0x? | Unknown Flag |
Custom File Formats |
|||
Package File (PAK) - found in Digimon Games - groups files (ie Palette/Graphic/Animation) either in separate PAK files for each type, or in a single file with each file in an ordered manner - no filenames so referencing should be done by the index in the offset table (see below) - each file is compressed |
|||
Section Offsets | |||
Offset | Length | Name | Description |
0x0 | 0x4 | Number of Files | |
DATA | |||
0x4 | File Start Offset | ||
0x4 | File Size | ||
PAK5 Files - known file formats with a custom 5 byte header added before the start of the normal file format - found in PAK files and files in the normal file system of Digimon Games (named using a combination of a hex number and letter representing what format the file contains) |
|||
Compression Formats |
|||
Files may be stored using a variety of different compression formats including LZ77, Huffman and RLUncomp. Because there's a real lack of good easy to understand documentation on it (and trust me I know in order to be able to write this), I'm going to write my interpretations here. Generally the filenames of files will indicate whether or not they are compressed, but otherwise you have to guess it on your own. For starters if while looking at a file in a Hex Editor, the first 5 Bytes are then followed by a Magic ID, then it is almost guaranteed to be a compressed known file format, and this is where documentation helps! So first off we have a look at the first 4 Bytes or rather first 32 Bits, keeping in mind that the Nintendo DS works from right to left (Least Significant to Most Significant), which is Little Endian if you aren't very familiar with stuff like that. |
|||
Compression Header (Same for all types) | |||
Offset (Bits) | Length (Bits) | Name | Description |
0x0 | 0x4 | Reserved / Compression Size | Should always be (0x0) unless Compression Type is Huffman, in which case this specifies the Compression Size. |
0x4 | 0x4 | Compression Type | Specifies what type of compression is used. 1 = LZ77 2 = Huffman 3 = RLUncomp |
0x8 | 0x24 | Decompressed File Size | The size the file will be after being decompressed. |
After the header comes the compressed data, and depending on what Compression Type it is will affect how it is stored. | |||
#1 Type - LZ77 Compression | |||
0x0 | 0x8 | Flag | Each Bit tells if the corresponding Block of Data is compressed or uncompressed. 0 = Uncompressed 1 = Compressed |
0x8 | Uncompressed Data | No decompression needed, single byte can be copied to the end of the place where the decompressed file is being stored. | |
0x16 | Compressed Reference | Format is (MMMMNNNNLLLLLLLL) M4 = Most significant Bits N4 = Number of Bytes to be copied L8 = Least significant Bits Copy Offset = (L8 | M4 << 8) +1 |
|
So when the decompressor finds a compressed block, it copies N+3 Bytes from the current position in the decompressed file minus the Copy Offset.
An important thing to note is that if the Copy Count greater than the distance between the Copy Offset and the Current Offset in the decompressed file, the data is repeatedly copied until it matches the Copy Count. This will often occur when the compressed data has the same value. |
|||
#2 Type - Huffman Compression | |||
#3 Type - RL Compression | |||
0x0 | 0x7 | Expanded Length / Copy Count | If the Flag is 0 this specifies how many bytes after the flag are copied to where the decompressed file is being stored. Otherwise it specifies how many times the next byte is copied to where the decompressed file is being stored. |
0x7 | 0x1 | Flag | 0 = Uncompressed (Add 1 to the Copy Count) 1 = Compressed (Add 3 to the Expanded Length) |
This is much simpler than the other two formats as you are only copying bytes from the source file to the decompressed file. |